package com.zeng.sys.authmd.servicemodule.service.serviceimpl;

import com.baomidou.mybatisplus.core.conditions.AbstractWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zeng.nicecore.constant.IgnoreConstant;
import com.zeng.nicecore.util.BeanUtil;
import com.zeng.nicecore.util.IgnoreStringUtil;
import com.zeng.nicecore.wrapper.QWrapper;
import com.zeng.sys.authmd.apimodule.service.PermissionService;
import com.zeng.sys.authmd.apimodule.service.RoleService;
import com.zeng.sys.authmd.apimodule.vo.PermissionVo;
import com.zeng.sys.authmd.apimodule.vo.RoleVo;
import com.zeng.sys.authmd.servicemodule.convert.RolePermissionVoConvert;
import com.zeng.sys.authmd.servicemodule.mapper.RolePermissionMapper;
import com.zeng.sys.authmd.servicemodule.entity.RolePermission;
import com.zeng.sys.authmd.apimodule.vo.RolePermissionVo;
import com.zeng.sys.authmd.apimodule.service.RolePermissionService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

@Service
@Transactional
public class RolePermissionServiceImpl implements RolePermissionService {

    @Autowired
    RolePermissionMapper rolePermissionMapper;

    @Autowired
    RoleService roleService;

    @Autowired
    PermissionService permissionService;

    @Override
    public RolePermissionVo addOne(RolePermissionVo rolePermissionVo) {
    RolePermission rolePermission = RolePermission.builder().build();
    BeanUtils.copyProperties(rolePermissionVo, rolePermission, IgnoreStringUtil.ignoreExclude());
    int insert = rolePermissionMapper.insert(rolePermission);
    return BeanUtil.beanToVo(rolePermission, rolePermissionVo);
    }

    @Override
    public RolePermissionVo getOneByCode(String code) {

    RolePermission rolePermission = this.rolePermissionMapper.selectById(code);
    RolePermissionVo rolePermissionVo = BeanUtil.beanToVo(rolePermission, new RolePermissionVo());

    return rolePermissionVo;
    }

    @Override
    public Integer update(RolePermissionVo rolePermissionVo) {
    RolePermission rolePermission = BeanUtil.VoToBean(rolePermissionVo,
    new RolePermission(),
    IgnoreStringUtil.ignoreExclude(IgnoreConstant.code.getValue()));
    return this.rolePermissionMapper.updateById(rolePermission);
    }

    @Override
    public Integer delete(String code) {
    return this.rolePermissionMapper.deleteById(code);
    }

    @Override
    public Integer batchDelete(List<String> codes) {

    return this.rolePermissionMapper.deleteBatchIds(codes);
    }

    @Override
    public List<RolePermissionVo> findPage(Page page, RolePermissionVo rolePermissionVo) {
        this.rolePermissionMapper.selectPage(page, this.getWrapper(rolePermissionVo));
        List orders = page.getRecords();
        List<RolePermissionVo> rolePermissionVos = new ArrayList<>();
        orders.forEach(e->{
            rolePermissionVos.add(BeanUtil.beanToVo(e, new RolePermissionVo()));
        });
        page.setRecords(null);
        return rolePermissionVos;
        }

    @Override
    public List<RolePermissionVo> findAll(RolePermissionVo rolePermissionVo) {
        return new RolePermissionVoConvert().toList(rolePermissionMapper.selectList(getWrapper(rolePermissionVo)));
    }
    @Override
    public Integer count(RolePermissionVo rolePermissionVo) {
        Integer integer = this.rolePermissionMapper.selectCount(this.getWrapper(rolePermissionVo));
        return integer;
    }

    @Override
    public void addRoleAndInitRolePermission(RoleVo roleVo) {
        if (roleVo == null) {
            return;
        }
        RoleVo role;
        if (roleVo.getCode() == null) {
             role = roleService.addOne(roleVo);
        } else {
            roleService.update(roleVo);
            role = roleVo;
        }
        String roleCode = role.getCode();
        if (roleCode == null) {
            return;
        }
        if (roleVo.getMenuCodes() == null) {
            roleVo.setMenuCodes(Collections.emptyList());
        }
        if (roleVo.getApiCodes() == null) {
            roleVo.setApiCodes(Collections.emptyList());
        }
        for (String apiCode : roleVo.getApiCodes()) {
            rolePermissionMapper.insert(RolePermission.builder().roleCode(roleCode).permissionCode(apiCode).build());
        }
        for (String menuCode : roleVo.getMenuCodes()) {
            rolePermissionMapper.insert(RolePermission.builder().roleCode(roleCode).permissionCode(menuCode).build());
        }
    }

    @Override
    public void updateRoleAndInitRolePermission(RoleVo roleVo) {
        if (roleVo == null) {
            return;
        }
        QueryWrapper wrapper = new QWrapper();
        wrapper.eq(RolePermission.Fields.roleCode, roleVo.getCode());
        rolePermissionMapper.delete(wrapper);
        this.addRoleAndInitRolePermission(roleVo);
    }

    @Override
    public Integer deleteByPermissionCode(String code) {
        AbstractWrapper wrapper = getWrapper(null);
        wrapper.eq(RolePermission.Fields.permissionCode, code);
        return rolePermissionMapper.delete(wrapper);
    }

    @Override
    public Integer deleteByRoleCode(String code) {
        AbstractWrapper wrapper = getWrapper(null);
        wrapper.eq(RolePermission.Fields.roleCode, code);
        return rolePermissionMapper.delete(wrapper);
    }

    @Override
    public Integer batchDeleteByPermissionCode(List<String> codes) {
        AbstractWrapper wrapper = getWrapper(null);
        wrapper.in(RolePermission.Fields.permissionCode, codes);
        return rolePermissionMapper.delete(wrapper);
    }

    @Override
    public Integer batchDeleteByRoleCodes(List<String> codes) {
        AbstractWrapper wrapper = getWrapper(null);
        wrapper.in(RolePermission.Fields.roleCode, codes);
        return rolePermissionMapper.delete(wrapper);
    }

    @Override
    public List<RolePermissionVo> listPermissionByRoleCodes(List<String> roleCodes) {
        if (roleCodes == null) {
            return Collections.emptyList();
        }
        AbstractWrapper wrapper = this.getWrapper(null);
        wrapper.in(RolePermission.Fields.roleCode, roleCodes);
        List list = rolePermissionMapper.selectList(wrapper);

        return new RolePermissionVoConvert().toList(list);
    }

    public AbstractWrapper getWrapper(RolePermissionVo rolePermissionVo) {
        QueryWrapper<RolePermission> wrapper = new QWrapper<>();
        if (rolePermissionVo != null) {
            if (rolePermissionVo.getRoleCode() != null) {
                wrapper.eq(RolePermission.Fields.roleCode, rolePermissionVo.getRoleCode());
            }
        }
        return wrapper;
    }
}
